#!/bin/bash
#
# note "file crypto" related file
# Copyright (C) 2023 Dramalife@live.com
# 
# This file is part of [note](https://github.com/Dramalife/note.git)
# 
# note is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# 1. Init : Sat 17 Jun 2023 09:05:07 PM CST
#      Ref "decrypt.sh" and "encrypt-FloderPasswdOutpath.sh"
#        of [note]/80-userspace_programming/script, and replace.
#

set -e
#set -x

readonly MODE_ENCRYPT="ENcrypt"
readonly MODE_DECRYPT="DEcrypt"
readonly SUFFIX_DES3=".des3"

c_info(){
  echo -e "INFO : $@"
}
c_fatal(){
  echo -e "FATAL: $@\n"
  c_help
  exit 1
}
c_help(){
  readonly S_OPTS_NLR="  %-16s  %s"
  readonly S_OPTS="${S_OPTS_NLR} \n"
  printf "Usage: \n"
  printf "  %s <Input> <Output> [Options] \n" $0
  printf "\nOptions: \n"
  printf "$S_OPTS" "[-P <password>]" "Set password, or read from stdin later"
  printf "$S_OPTS_NLR %s \n" "[-e | -d]" "Set Encrypt OR Decrypt mode," \
                     "guess if neither \"-e\" nor \"-d\" is set"
  printf "\nGuess Mode: \n"
  printf "  Grep the suffix \"%s\" in <Input> and <Output> \n" $SUFFIX_DES3
}
c_check_e(){
  if [ ! -e $1 ] ; then
    c_fatal "($1): No such file or directory"
  fi
}

# Check Args` Num
[[ $# -lt 2 ]] && c_help

# Args - Input && Output
INPUT=$1
OUTPUT=$2
shift 2

# Args - Options
while getopts "P:ed" opt ; do
  case $opt in
    P)
      PASSWORD=$OPTARG
      ;;
    e)
      MODE=$MODE_ENCRYPT
      ;;
    d)
      MODE=$MODE_DECRYPT
      ;;
  esac
done

# Read Password
if [ ${#PASSWORD} -eq 0 ] ; then
  echo "Input password:"
  stty -echo
  read PASSWORD
  stty echo
fi

# Parse Crypto Mode
if [ ${#MODE} -eq 0 ] ; then
  tmp_in=0
  tmp_out=0
  if echo $INPUT | grep $SUFFIX_DES3 > /dev/null ; then
    tmp_in=1
  fi
  if echo $OUTPUT | grep $SUFFIX_DES3 > /dev/null ; then
    tmp_out=1
  fi
  if [ $tmp_in -eq 1 -a $tmp_out -eq 0 ] ; then
    MODE=$MODE_DECRYPT
  elif [ $tmp_in -eq 0 -a $tmp_out -eq 1 ] ; then
    MODE=$MODE_ENCRYPT
  else
    c_fatal "Guess MODE failed!"
  fi
  c_info "Guessed MODE: $MODE"
fi

# Check Password
[[ ${#PASSWORD} -eq 0 ]] && c_fatal "Length of password"

# Check Input
c_check_e $INPUT

# Check Mode
if [ "x$MODE" != "x$MODE_ENCRYPT" -a "x$MODE" != "x$MODE_DECRYPT" ] ; then
  c_fatal "Error Mode ($MODE)"
fi

# Encrypt
if [ "x$MODE" == "x$MODE_ENCRYPT" ] ; then
  c_info "Encrypt ..."

  tar -zcf - $INPUT | openssl des3 -salt -k $PASSWORD -out $OUTPUT
fi

# Decrypt
if [ "x$MODE" == "x$MODE_DECRYPT" ] ; then
  c_info "Decrypt ..."

  if [ ! -e $OUTPUT ] ; then
    mkdir -p $OUTPUT
  fi
  c_check_e $OUTPUT

  openssl des3 -d -k $PASSWORD -in $INPUT | tar -z -x -f - -C $OUTPUT
fi
